package services;

import java.io.InputStream;
import java.util.List;
import java.util.concurrent.Callable;

import org.codehaus.jackson.JsonNode;

import play.libs.Akka;
import play.libs.F.Promise;
import collectors.calendar.models.CalendarUser;
import collectors.calendar.models.Event;
import collectors.calendar.services.GCalendarWrapper;
import collectors.email.models.EmailUser;
import collectors.email.models.GmailEmail;
import collectors.email.services.GoogleService;
import collectors.file.models.FileInfo;
import collectors.file.models.FileUser;
import collectors.file.wrapper.DropboxWrapper;
import collectors.people.models.PeopleUser;
import collectors.people.models.PeopleUser.FacebookData;
import collectors.people.services.FacebookQueryService;

class LocalCollectorService extends CollectorService {

	public static LocalCollectorService instance;

	private LocalCollectorService() {}

	public static CollectorService get() {
		if (instance == null) {
			instance = new LocalCollectorService();
		}
		return instance;
	}

	@Override
	Promise<List<Event>> searchEventsImpl(Long calUserId, String query) {
		return GCalendarWrapper.search(calUserId, query);
	}

	@Override
	Promise<List<Event>> getEventDetailsImpl(Long calUserId, String eventId) {
		throw new RuntimeException("Operation not implemented by CalendarYOU");
	}

	@Override
	Promise<List<GmailEmail>> searchEmailsImpl(Long gmailUserId, String query, int max) {
		return GoogleService.search(gmailUserId, query, max);
	}

	@Override
	Promise<List<FileInfo>> getMetadataImpl(Long fileUserId, String path) {
		try {
			return DropboxWrapper.getMetadataAsync(fileUserId, path);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	Promise<List<FileInfo>> searchFilesImpl(Long fileUserId, String query,
			String path) {
		try {
			return DropboxWrapper.searchAsync(fileUserId, query, path);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	Promise<InputStream> getFileImpl(Long fileUserId, String path) {
		try {
			return DropboxWrapper.getFileAsync(fileUserId, path);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	//TODO put data on facebookData
	Promise<JsonNode> getPeopleUserDataImpl(Long peopleUserId) {
		return FacebookQueryService.getUserData(peopleUserId);
	}

	@Override
	Promise<List<FacebookData>> searchPeopleImpl(Long peopleUserId, String query) {
		return FacebookQueryService.searchUserModel(peopleUserId, query);
	}

	@Override
	Promise<Long> createPeopleUser() {
		return Akka.future(new Callable<Long>() {
			@Override
			public Long call() throws Exception {
				 return PeopleUser.create().youId;
			}
		});
	}

	@Override
	Promise<Long> createFileUser() {
		return Akka.future(new Callable<Long>() {
			@Override
			public Long call() throws Exception {
				 return FileUser.create().id;
			}
		});
	}

	@Override
	Promise<Long> createEmailUser() {
		return Akka.future(new Callable<Long>() {
			@Override
			public Long call() throws Exception {
				 return EmailUser.create().youId;
			}
		});
	}

	@Override
	Promise<Long> createCalendarUser() {
		return Akka.future(new Callable<Long>() {
			@Override
			public Long call() throws Exception {
				 return CalendarUser.create().youId;
			}
		});
	}

	@Override
	String getBaseUrlImpl(Services service) {
		return play.Play.application().configuration().getString("you.baseurl");
	}
}
